package com.wsd.bookkeeping.service.impl;

import com.wsd.bookkeeping.entity.query.AccountRecordStatisticQuery;
import com.wsd.bookkeeping.enums.RecordStyle;
import com.wsd.bookkeeping.mapper.AccountStatisticMapper;
import com.wsd.bookkeeping.service.AccountStatisticService;
import com.wsd.bookkeeping.vo.StatisticRangeAmountVO;
import com.wsd.common.utils.Pair;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class AccountStatisticServiceImpl implements AccountStatisticService {

    @Resource
    private AccountStatisticMapper accountStatisticMapper;

    @Override
    public Pair<Map<Integer, BigDecimal>, Map<Integer, BigDecimal>> getAccountMonthRangeAmount(Integer bookId, Integer year) throws InterruptedException {

        String startDate = year + "0101";
        String endDate = year + "1231";
        Pair<Map<Integer, BigDecimal>, Map<Integer, BigDecimal>> pair = new Pair<>();

        ExecutorService executorService = Executors.newFixedThreadPool(2);
        CountDownLatch countDownLatch = new CountDownLatch(2);

        Function<RecordStyle, Runnable> function = (style) -> () -> {
            AccountRecordStatisticQuery query = new AccountRecordStatisticQuery();
            query.setStartDate(startDate);
            query.setEndDate(endDate);
            query.setBookId(bookId);
            query.setStyle(style.getType());

            List<StatisticRangeAmountVO> rangeAmountList = accountStatisticMapper.countRecordOfYear(query);
            Map<Integer, BigDecimal> collect = rangeAmountList.stream().collect(Collectors.toMap(StatisticRangeAmountVO::getDate, StatisticRangeAmountVO::getTotal));
            for (int i = 1; i <= 12; i++) {
                if (!collect.containsKey(i)) {
                    collect.put(i, BigDecimal.ZERO);
                }
            }
            if (style == RecordStyle.INCOME) {
                pair.setLeft(collect);
            } else if (style == RecordStyle.OUTCOME) {
                pair.setRight(collect);
            }
            countDownLatch.countDown();
        };

        executorService.execute(function.apply(RecordStyle.INCOME));
        executorService.execute(function.apply(RecordStyle.OUTCOME));
        countDownLatch.await();

        return pair;
    }
}
